#include <boost/test/unit_test.hpp>

#include <vector>
#include "../src/OverlappingRegions.h"

using namespace std;

BOOST_AUTO_TEST_CASE( OverlappingRegionsTest )
{
	OverlappingRegions regions;
	regions.add(1, -3, 10);
	regions.add(1, 30, 40);
	regions.add(1, 21, 21);
	regions.add(2, 10, 100);
	regions.add(1, 50, 60);
	regions.add(1, 11, 20);
	regions.add(1, 31, 41);
	regions.add(2, 20, 150);

	BOOST_CHECK(!regions.overlapsWith(3,1,100));
	BOOST_CHECK(regions.overlapsWith(1,1,100));
	BOOST_CHECK(!regions.overlapsWith(1,-10,-4));
	BOOST_CHECK(regions.overlapsWith(1,-10,-3));
	BOOST_CHECK(regions.overlapsWith(1,10,10));
	BOOST_CHECK(regions.overlapsWith(1,11,11));
	BOOST_CHECK(regions.overlapsWith(1,-5,25));
	BOOST_CHECK(!regions.overlapsWith(1,22,29));
	BOOST_CHECK(regions.overlapsWith(1,21,29));
	BOOST_CHECK(regions.overlapsWith(1,22,30));
	BOOST_CHECK(regions.overlapsWith(1,30,31));
	BOOST_CHECK(!regions.overlapsWith(2,1,9));
	BOOST_CHECK(regions.overlapsWith(2,150,150));
	BOOST_CHECK(!regions.overlapsWith(2,151,20000));

	const vector<OverlappingRegions::interval_t>& intervals = regions.list();
	BOOST_CHECK_EQUAL(intervals.size(), 4);
	BOOST_CHECK_EQUAL(intervals[0].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals[0].start, -3);
	BOOST_CHECK_EQUAL(intervals[0].end, 21);
	BOOST_CHECK_EQUAL(intervals[1].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals[1].start, 30);
	BOOST_CHECK_EQUAL(intervals[1].end, 41);
	BOOST_CHECK_EQUAL(intervals[2].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals[2].start, 50);
	BOOST_CHECK_EQUAL(intervals[2].end, 60);
	BOOST_CHECK_EQUAL(intervals[3].chromosome_id, 2);
	BOOST_CHECK_EQUAL(intervals[3].start, 10);
	BOOST_CHECK_EQUAL(intervals[3].end, 150);

	OverlappingRegions regions1;
	regions1.add(1, 1000, 1010);
	regions1.add(2, 10, 100);

	OverlappingRegions regions2;
	regions2.add(1, 1005, 1050);
	regions2.add(2, 0, 9);
	regions2.add(regions1);
	const vector<OverlappingRegions::interval_t>& intervals2 = regions2.list();
	BOOST_CHECK_EQUAL(intervals2.size(), 2);
	BOOST_CHECK_EQUAL(intervals2[0].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals2[0].start, 1000);
	BOOST_CHECK_EQUAL(intervals2[0].end, 1050);
	BOOST_CHECK_EQUAL(intervals2[1].chromosome_id, 2);
	BOOST_CHECK_EQUAL(intervals2[1].start, 0);
	BOOST_CHECK_EQUAL(intervals2[1].end, 100);
	
	OverlappingRegions regions3;
	regions3.add(1, 22, 29);
	regions3.add(1, 41, 50);
	regions3.add(2, 15, 25);
	regions3.add(2, 101, 105);
	regions.subtract(regions3);
	const vector<OverlappingRegions::interval_t>& intervals3 = regions.list();
	BOOST_CHECK_EQUAL(intervals3.size(), 6);
	BOOST_CHECK_EQUAL(intervals3[0].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals3[0].start, -3);
	BOOST_CHECK_EQUAL(intervals3[0].end, 21);
	BOOST_CHECK_EQUAL(intervals3[1].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals3[1].start, 30);
	BOOST_CHECK_EQUAL(intervals3[1].end, 40);
	BOOST_CHECK_EQUAL(intervals3[2].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals3[2].start, 51);
	BOOST_CHECK_EQUAL(intervals3[2].end, 60);
	BOOST_CHECK_EQUAL(intervals3[3].chromosome_id, 2);
	BOOST_CHECK_EQUAL(intervals3[3].start, 10);
	BOOST_CHECK_EQUAL(intervals3[3].end, 14);
	BOOST_CHECK_EQUAL(intervals3[4].chromosome_id, 2);
	BOOST_CHECK_EQUAL(intervals3[4].start, 26);
	BOOST_CHECK_EQUAL(intervals3[4].end, 100);
	BOOST_CHECK_EQUAL(intervals3[5].chromosome_id, 2);
	BOOST_CHECK_EQUAL(intervals3[5].start, 106);
	BOOST_CHECK_EQUAL(intervals3[5].end, 150);
	
	OverlappingRegions regions4;
	regions4.add(1, 100, 200);
	OverlappingRegions regions5;
	regions5.add(1, 100, 200);
	regions4.subtract(regions5);
	BOOST_CHECK_EQUAL(regions4.list().size(), 0);

	OverlappingRegions regions6;
	regions6.add(1, 100, 200);
	OverlappingRegions regions7;
	regions7.add(1, 101, 199);
	regions6.subtract(regions7);
	const vector<OverlappingRegions::interval_t>& intervals6 = regions6.list();
	BOOST_CHECK_EQUAL(intervals6.size(), 2);
	BOOST_CHECK_EQUAL(intervals6[0].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals6[0].start, 100);
	BOOST_CHECK_EQUAL(intervals6[0].end, 100);
	BOOST_CHECK_EQUAL(intervals6[1].chromosome_id, 1);
	BOOST_CHECK_EQUAL(intervals6[1].start, 200);
	BOOST_CHECK_EQUAL(intervals6[1].end, 200);
}

BOOST_AUTO_TEST_CASE( OverlappingRegionsTest2 ) {
	OverlappingRegions regions1;
	regions1.add(1,10,30);
	regions1.add(1,20,40);
	OverlappingRegions regions2;
	regions2.add(1,10,19);
	regions2.add(1,20,40);
	
	regions1.subtract(regions2);
	BOOST_CHECK_EQUAL(regions1.list().size(), 0);
}
